#include <bits/stdc++.h>
#define double long double
#define int long long
using namespace std;

struct node
{
    double d, v, a;
} car[100001];
double p[100001];
bool flag[100001];
vector<pair<int, int> > vec;
bool useful[100001];
signed main()
{
    freopen("detect.in", "r", stdin);
    freopen("detect.out", "w", stdout);
    int t;
    cin >> t;
    while (t--)
    {
        memset(flag, 0, sizeof flag);
        memset(useful, 1, sizeof useful);
        vec.clear();
        int n, m;
        double L, V;
        cin >> n >> m >> L >> V;
        for (int i = 1; i <= n; i++) cin >> car[i].d >> car[i].v >> car[i].a;
        for (int i = 1; i <= m; i++) cin >> p[i];
        int cnt = 0;
        for (int i = 1; i <= n; i++)
        {
            double bg = car[i].d;
            double ed;
            if (car[i].a >= 0) ed = L;
            else
            {
                double edtime = -(1.0 * car[i].v / car[i].a);
                double eds = car[i].v * edtime + 0.5 * car[i].a * edtime * edtime + car[i].d;
                ed = min(eds, L);
            }
            if (car[i].a == 0)
            {
                if (V < car[i].v)
                {
                    int lb = lower_bound(p + 1, p + m + 1, bg) - p;
                    int rb = upper_bound(p + 1, p + m + 1, ed) - p - 1;
                    if (lb <= rb)
                    {
                        flag[i] = 1;
                        cnt++;
                        vec.push_back(make_pair(lb, rb));
                    }
                }
            }
            else if (car[i].a > 0)
            {
                double lb1 = (V * V - car[i].v * car[i].v) / (2.0 * car[i].a) + bg;
                double lb2 = bg;
                double rb1 = ed;
                int llb1 = upper_bound(p + 1, p + m + 1, lb1) - p;
                int llb2 = lower_bound(p + 1, p + m + 1, lb2) - p;
                int rrb1 = upper_bound(p + 1, p + m + 1, rb1) - p - 1;
                int lb = max(llb1, llb2);
                int rb = rrb1;
                if (lb <= rb)
                {
                    flag[i] = 1;
                    cnt++;
                    vec.push_back(make_pair(lb, rb));
                }
            }
            else if (car[i].a < 0)
            {
                double lb1 = bg;
                double rb1 = (V * V - car[i].v * car[i].v) / (2.0 * car[i].a) + bg;
                double rb2 = ed;
                int llb1 = lower_bound(p + 1, p + m + 1, lb1) - p;
                int rrb1 = lower_bound(p + 1, p + m + 1, rb1) - p - 1;
                int rrb2 = upper_bound(p + 1, p + m + 1, rb2) - p - 1;
                int lb = llb1;
                int rb = min(rrb1, rrb2);
                if (lb <= rb)
                {
                    flag[i] = 1;
                    cnt++;
                    vec.push_back(make_pair(lb, rb));
                }
            }
        }
        cout << cnt << ' ';
        sort(vec.begin(), vec.end());
        int rightmost = 0;
        int ans2 = 0;
        int minv = 100001;
        for (int i = vec.size() - 1; i >= 0; i--)
        {
            if (vec[i].second > minv) useful[i] = 0;
            minv = min(minv, vec[i].second);
        }
        for (int i = 0; i < vec.size(); i++)
        {
            if (!useful[i]) continue;
            if (vec[i].first > rightmost)
            {
                rightmost = vec[i].second;
                ans2++;
            }
        }
        cout << m - ans2 << endl;
    }
    return 0;
}
